package com.huiminpay.merchant.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.huiminpay.common.cache.domain.BusinessException;
import com.huiminpay.common.cache.domain.CommonErrorCode;
import com.huiminpay.common.cache.domain.PageVO;
import com.huiminpay.common.cache.util.PhoneUtil;
import com.huiminpay.common.cache.util.StringUtil;
import com.huiminpay.merchant.api.MerchantService;
import com.huiminpay.merchant.convert.MerchantConvert;
import com.huiminpay.merchant.convert.StaffConvert;
import com.huiminpay.merchant.convert.StoreConvert;
import com.huiminpay.merchant.dto.MerchantDTO;
import com.huiminpay.merchant.dto.StaffDTO;
import com.huiminpay.merchant.dto.StoreDTO;
import com.huiminpay.merchant.entity.Merchant;
import com.huiminpay.merchant.entity.Staff;
import com.huiminpay.merchant.entity.Store;
import com.huiminpay.merchant.entity.StoreStaff;
import com.huiminpay.merchant.mapper.MerchantMapper;
import com.huiminpay.merchant.mapper.StaffMapper;
import com.huiminpay.merchant.mapper.StoreMapper;
import com.huiminpay.merchant.mapper.StoreStaffMapper;
import com.huiminpay.user.api.TenantService;
import com.huiminpay.user.api.dto.tenant.CreateTenantRequestDTO;
import com.huiminpay.user.api.dto.tenant.TenantDTO;
import org.apache.dubbo.config.annotation.Reference;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;


@Service  //dubbo注解
public class MerchantServiceImpl implements MerchantService {
    @Autowired
    MerchantMapper merchantMapper;
    @Autowired
    StoreMapper storeMapper;
    @Autowired
    StaffMapper staffMapper;
    @Autowired
    StoreStaffMapper storeStaffMapper;
    @Reference
    TenantService tenantService;


    /**
     * 根据id查询商户
     *
     * @param merchantId 商户Id
     * @return 商户信息
     */
    @Override
    public MerchantDTO queryMerchantById(Long merchantId) {
        Merchant merchant = merchantMapper.selectById(merchantId);
//        MerchantDTO merchantDTO = new MerchantDTO();
//        //MerchantDTO merchantDTO1 = JSON.parseObject(JSON.toJSONString(merchant), MerchantDTO.class);
//        BeanUtils.copyProperties(merchant,merchantDTO);

        //.....

        //return merchantDTO;


        return MerchantConvert.INSTANCE.entity2DTO(merchant);
    }

    /**
     * 新增商户
     *
     * @param merchantDTO 商户信息
     * @return 新添加的商户信息
     */
    @Override
    public MerchantDTO createMerchant(MerchantDTO merchantDTO) throws BusinessException {

        //校验
        if (merchantDTO == null) {
            throw new BusinessException(CommonErrorCode.E_100108);
        }

        // 手机号非空校验
        if (merchantDTO.getMobile() == null) {
            throw new BusinessException(CommonErrorCode.E_100112);
        }

        //手机号格式校验
        if (!PhoneUtil.isMatches(merchantDTO.getMobile())) {
            throw new BusinessException((CommonErrorCode.E_100109));
        }

        //用户名
        if (merchantDTO.getUsername() == null) {
            throw new BusinessException(CommonErrorCode.E_100110);
        }
        //密码为空
        if (merchantDTO.getPassword() == null) {
            throw new BusinessException(CommonErrorCode.E_100111);
        }

        //手机号唯一校验
        Integer count = merchantMapper.selectCount(new LambdaQueryWrapper<Merchant>().eq(Merchant::getMobile, merchantDTO.getMobile()));
        if (count > 0) {
            throw new BusinessException(CommonErrorCode.E_100113);
        }

        // 调用Saas平台接口新增租户
        /*
            接口参数：
            1、手机号
            2、账号
            3、密码
            4、租户类型：huimin-merchant
            5、默认套餐：huimin-merchant
            6、租户名称，同账号名
         */
        CreateTenantRequestDTO tenantRequestDTO = new CreateTenantRequestDTO();
        tenantRequestDTO.setMobile(merchantDTO.getMobile());
        tenantRequestDTO.setUsername(merchantDTO.getUsername());
        tenantRequestDTO.setPassword(merchantDTO.getPassword());
        tenantRequestDTO.setBundleCode("huimin-merchant");
        tenantRequestDTO.setName(merchantDTO.getUsername());

        TenantDTO tenantDTO = tenantService.createTenantAndAccount(tenantRequestDTO);
        //获取租户Id
        Long tenantId = tenantDTO.getId();
        if (tenantId == null) {
            throw new BusinessException(CommonErrorCode.E_200012);
        }

        //商户和租户是一一对应的
        Integer num = merchantMapper.selectCount(new LambdaQueryWrapper<Merchant>().eq(Merchant::getTenantId, tenantId));
        if (num > 0) {
            throw new BusinessException(CommonErrorCode.E_200017);
        }


        //设置租户Id
        Merchant merchant = MerchantConvert.INSTANCE.dto2Entity(merchantDTO);
        merchant.setTenantId(tenantId);
        //状态
        merchant.setAuditStatus("0");

        merchantMapper.insert(merchant);

        //新增门店
        StoreDTO storeDTO = new StoreDTO();
        storeDTO.setMerchantId(merchant.getId());
        storeDTO.setStoreAddress("杭州");
        storeDTO.setStoreName("根门店");
        storeDTO.setStoreNumber(001L);
        storeDTO.setStoreStatus(true);
        StoreDTO store = createStore(storeDTO);


        //新增员工
        StaffDTO staffDTO = new StaffDTO();
        staffDTO.setMerchantId(merchant.getId());
        staffDTO.setMobile(merchant.getMobile());
        staffDTO.setStaffStatus(true);
        staffDTO.setStoreId(store.getId());
        staffDTO.setUsername(merchant.getUsername());
        StaffDTO staff = createStaff(staffDTO);


        //为门店设置管理员
        bindStaffToStore(store.getId(), staff.getId());


        return MerchantConvert.INSTANCE.entity2DTO(merchant);
    }

    /**
     * 资质申请
     *
     * @param merchantId  商户id
     * @param merchantDTO 商户信息
     * @throws BusinessException
     */
    @Override
    public void applyMerchant(Long merchantId, MerchantDTO merchantDTO) throws BusinessException {
        //参数校验
        if (merchantId == null || merchantDTO == null) {
            throw new BusinessException(CommonErrorCode.E_100108);
        }

        //id合法性校验
        Merchant merchant = merchantMapper.selectById(merchantId);
        if (merchant == null) {
            throw new BusinessException(CommonErrorCode.E_200002);
        }

        //将DTO转为entity
        Merchant entity = MerchantConvert.INSTANCE.dto2Entity(merchantDTO);

        //设置必要数据
        entity.setId(merchantId);
        entity.setMobile(merchant.getMobile());
        entity.setAuditStatus("1");//已申请待审核
        entity.setTenantId(merchant.getTenantId());

        merchantMapper.updateById(entity);
    }

    /**
     * 新增门店
     *
     * @param storeDTO 门店信息
     * @return 新增的门店信息
     * @throws BusinessException
     */
    @Override
    public StoreDTO createStore(StoreDTO storeDTO) throws BusinessException {
        Store store = StoreConvert.INSTANCE.dto2entity(storeDTO);
        storeMapper.insert(store);
        StoreDTO storeDTO1 = StoreConvert.INSTANCE.entity2dto(store);
        return storeDTO1;
    }

    /**
     * 新增员工
     *
     * @param staffDTO 员工信息
     * @return 新增的员工信息
     * @throws BusinessException
     */
    @Override
    public StaffDTO createStaff(StaffDTO staffDTO) throws BusinessException {

        //参数校验

        //用户名  手机号非空校验
        if (staffDTO == null || StringUtil.isBlank(staffDTO.getMobile()) || StringUtil.isBlank(staffDTO.getUsername())) {
            throw new BusinessException(CommonErrorCode.E_300009);
        }

        //同一商户中员工手机号唯一性校验
        if (isExistStaffByMobile(staffDTO.getMerchantId(), staffDTO.getMobile())) {
            throw new BusinessException(CommonErrorCode.E_100113);
        }

        //同一商户中员工用户名唯一性校验
        if (isExistStaffByUsername(staffDTO.getMerchantId(), staffDTO.getUsername())) {
            throw new BusinessException(CommonErrorCode.E_100114);
        }

        Staff staff = StaffConvert.INSTANCE.dto2entity(staffDTO);
        staffMapper.insert(staff);
        return StaffConvert.INSTANCE.entity2dto(staff);
    }

    /**
     * 为门店设置管理员
     *
     * @param storeId 门店Id
     * @param staffId 员工Id
     * @throws BusinessException
     */
    @Override
    public void bindStaffToStore(Long storeId, Long staffId) throws BusinessException {
        StoreStaff storeStaff = new StoreStaff();
        storeStaff.setStoreId(storeId);
        storeStaff.setStaffId(staffId);
        storeStaffMapper.insert(storeStaff);

    }

    /**
     * 根据租户id查询商户信息
     *
     * @param tenantId 租户id
     * @return 商户信息
     */
    @Override
    public MerchantDTO queryMerchantByTenantId(Long tenantId) {
        Merchant merchant = merchantMapper.selectOne(new LambdaQueryWrapper<Merchant>().eq(Merchant::getTenantId, tenantId));
        return MerchantConvert.INSTANCE.entity2DTO(merchant);
    }

    /**
     * 分页查询门店列表
     *
     * @param storeDTO 商户ID,门店名称
     * @param pageNum  当前页码
     * @param pageSize 每页条数
     * @return
     * @throws BusinessException
     */
    @Override
    public PageVO<StoreDTO> queryStoreByPage(StoreDTO storeDTO, Integer pageNum, Integer pageSize) throws BusinessException {

        Page<Store> page = new Page<>(pageNum, pageSize);

        //构造查询条件
        LambdaQueryWrapper<Store> wrapper = new LambdaQueryWrapper<>();
        if (storeDTO != null && storeDTO.getMerchantId() != null) {
            wrapper.eq(Store::getMerchantId, storeDTO.getMerchantId());
        }
        IPage<Store> storeIPage = storeMapper.selectPage(page, wrapper);
        //分页查到的列表数据
        List<Store> records = storeIPage.getRecords();
        List<StoreDTO> storeDTOS = StoreConvert.INSTANCE.listentity2dto(records);
        //总记录数
        long total = storeIPage.getTotal();


//        PageVO
        return new PageVO<>(storeDTOS, total, pageNum, pageSize);
    }

    /**
     * 校验应用是否属于该商户
     *
     * @param storeId    门店Id
     * @param merchantId 商户Id
     * @return true:属于  false: 不属于
     * @throws BusinessException
     */
    @Override
    public Boolean queryStoreInMerchant(Long storeId, Long merchantId) throws BusinessException {
        Integer count = storeMapper.selectCount(new LambdaQueryWrapper<Store>()
                .eq(Store::getId, storeId)
                .eq(Store::getMerchantId, merchantId));
//        if (count>0) {
//            return true;
//        }
//        return false ;
        return count > 0;
    }

    /**
     * 同一商户中员工手机号唯一性校验
     *
     * @param merchantId 商户iId
     * @param phone      手机号
     * @return true/false
     */
    private boolean isExistStaffByMobile(Long merchantId, String phone) {
        Integer count = staffMapper.selectCount(new LambdaQueryWrapper<Staff>()
                .eq(Staff::getMerchantId, merchantId)
                .eq(Staff::getMobile, phone));
        return count > 0;
    }

    /**
     * 同一商户中员工用户名唯一性校验
     *
     * @param merchantId 商户iId
     * @param username   用户名
     * @return true/false
     */
    private boolean isExistStaffByUsername(Long merchantId, String username) {
        Integer count = staffMapper.selectCount(new LambdaQueryWrapper<Staff>()
                .eq(Staff::getMerchantId, merchantId)
                .eq(Staff::getUsername, username));
        return count > 0;
    }

}
